using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Trippy.Abilities;
using Trippy.Animation;
using Trippy.CollidableGameComponents.Objects;
using Trippy.CollidableGameComponents.Projectiles;
using Trippy.Levels;

// these enemies are pathing enemies
namespace Trippy.CollidableGameComponents.Agents
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    /// 

    public enum SlaveState {None, RotateIan, GoTo, ReturnIan}

    public class SlaveOrb : Agent
    {
        public static Texture2D SpriteSheet { get; private set; }

        private Vector2 target;

        public float ChaseSpeed { get; set; }

        public Ian Master { get; set; }

        public SlaveState State { get; set; }

        public int HitPoints { get; set; }

        public bool Frozen { get; set; }

        public void DoDamage(int damage)
        {
            HitPoints -= damage;

            Sprite.Tint = new Color(.3f + HitPoints / 5f, .2f + HitPoints / 5f, .4f + HitPoints / 5f);

            if (State == SlaveState.GoTo)
            {
                State = SlaveState.ReturnIan;
                target = Master.Position;
            }

            if (HitPoints < 1)
            {
                MarkForDeletion();
            }
        }

        public void Load()
        {
            LoadContent();
        }

        protected override void LoadContent()
        {
            if (SpriteSheet == null) SpriteSheet = CurrentLevel.Game.Content.Load<Texture2D>("Sprites/Agents/cat_original");
            Sprite = new AnimatedSprite(this, SpriteSheet, SpriteSheet.Height, SpriteSheet.Width, 0, 0, -5, -5, 1, 0f);
            base.LoadContent();

        }

        public override void Draw(GameTime gameTime)
        {
            if (HitPoints < 0) return;
            StandardDraw(gameTime);
            base.Draw(gameTime);
        }

        public void ChangeTarget(Vector2 position, float speed)
        {
            ChaseSpeed = speed;
            Velocity = ChaseSpeed * Vector2.Normalize(position - Position);
            target = position + Vector2.Normalize(position - Position);
        }

        public SlaveOrb(Level level)
            : base(level)
        {
            Friction = 0;
            State = SlaveState.None;
            Frozen = false;
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>

        public override void Update(GameTime gameTime)
        {

            float elapsedTime = TrippyUtilities.CalculateElapsedTime(gameTime);

            if (Frozen) return;

            switch (State)
            {
                case SlaveState.RotateIan:
                    break; // ian handles motion here
                case SlaveState.ReturnIan:
                case SlaveState.GoTo:
                    if (Vector2.DistanceSquared(Position, target) < 100f)
                    {
                        if (State == SlaveState.ReturnIan)
                        {
                            State = SlaveState.RotateIan;
                        }
                        else
                        {
                            State = SlaveState.ReturnIan;
                            target = Master.Position;
                        }
                    }
                    else
                    {
                       Position += Velocity * elapsedTime;
                       EffectAnimation effect = new EffectAnimation(CurrentLevel, EffectAnimation.Effects.IanCatFollow, Position);//;/ - 10 * Velocity);
                       effect.Scale = new Vector2(1.85f);
                       
                    }
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }


            base.Update(gameTime);
        }

        protected override void CollisionHandler(CollidableGameComponent component, CollidableGameComponent.CollisionSide side)
        {

            if (component is Hero)
            {
                     Hero h = (Hero)component;
                     h.Die(Hero.MannerOfDeath.Enemy);
            }

            if (component is WoodBox)
            {
                if (component.Acceleration != TrippyConstants.World.Gravity)
                {
                    component.Acceleration = TrippyConstants.World.Gravity;
                    EffectAnimation effectAnimation = new EffectAnimation(CurrentLevel, EffectAnimation.Effects.Pow, component.Position);
                }
            }
            if (component is UnpenetrableBeam)
            {
                if (State == SlaveState.GoTo)
                {
                    State = SlaveState.ReturnIan;
                    target = Master.Position;
                }
               
            }

            base.CollisionHandler(component, side);
        }

        public override void PostUpdate(float elapsedTime)
        {
            if (markedForDeletion)
            {
                Master.Slaves.Remove(this);
                CurrentLevel.Objects.Remove(this);
            }
        }

        /// <summary>
        /// Allows the game component to perform any initialization it needs to before starting
        /// to run.  This is where it can query for any required services and load content.
        /// </summary>
        public override void Initialize()
        {
            base.Initialize();
        }
    }
}
